package com.dorukdestan.p2pshare.network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import com.dorukdestan.p2pshare.logger.Logger;
import com.dorukdestan.p2pshare.model.Constants;
import com.dorukdestan.p2pshare.model.Protocol;
import com.dorukdestan.p2pshare.model.Protocol.ProtocolCommand;
import com.dorukdestan.p2pshare.storage.DownloadQueue;

public class FileTransferQueryServer implements Runnable{

	private Logger logger;
	private Socket socket;
	private ServerSocket serverSocket;
	private BufferedReader input;
	
	public FileTransferQueryServer() {
		this.logger = new Logger(getClass());
	}
	
	@Override
	public void run() {

		try {
			serverSocket = new ServerSocket(Constants.TCP_PORT_NUMBER);
			serverSocket.setReuseAddress(true);
		} catch (IOException e) {
			logger.error("FATAL: TCP server cannot be initialized!");
			logger.error(e);
		}
		
		while(true){
			try {
				//Receive packets
				socket = serverSocket.accept();
				
				//Drop own packet
				InetAddress peerAddress = socket.getInetAddress();
//				if(MyIp.get().contains(peerAddress))
//					continue;
//FIXME burayi ac				
				
				//Process query
				input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				String query = input.readLine();
				
				logger.debug("Query: " + query);
				
				//Get protocol and its arguments if any
				ProtocolCommand protocolCommand = Protocol.getProtocol(query);
				String[] protocolCommandArguments = Protocol.getProtocolArguments(query);
				
				switch (protocolCommand) {
					case DOWNLOAD_FILE://Here a peer requests the specified chunks of the specified file from us
						if (protocolCommandArguments.length == 3) {
							handleDownloadFileRequest(peerAddress,
									protocolCommandArguments[0],//fileHash
									protocolCommandArguments[1],//fileIndexStart
									protocolCommandArguments[2]);//fileIndexEnd
						}else{
							logger.error("DOWNLOAD_FILE wrong query");
						}
						break;
						
					case SENDING_FILE://Here we are downloading some file chunks from a peer
						if (protocolCommandArguments.length == 3) {
							handleIncomingFileChunk(protocolCommandArguments[0],//fileHash
												protocolCommandArguments[1], //fileIndex
												protocolCommandArguments[2]);//data
						}else{
							logger.error("SENDING_FILE wrong query");
						}
						break;
					
					default:
						logger.debug("Unrecognized protocol command! " + query);
						break;
				}
			} catch (IOException e) {
				logger.error("TCP server cannot accept socket");
				logger.error(e);
			}
		}
	}

	private void handleDownloadFileRequest(InetAddress peerAddress,
			String fileHash, String fileIndexStart, String fileIndexEnd) {

		new Thread(new SendingProcess(fileHash, fileIndexStart, fileIndexEnd, peerAddress)).start();
	}

	private void handleIncomingFileChunk(String fileHash, String fileIndex,
			String data) {
		DownloadQueue.handleIncomingFileChunk(fileHash, fileIndex, data);
	}

}
